
#include "config.h"
#include "ini.h"

#include <string.h>
#include <stdlib.h>

// L1 cache configuration variables
int L1_block_size;
int L1_cache_size;
int L1_assoc;
int L1_hit_time;
int L1_miss_time;

// L2 cache configuration variables
int L2_block_size;
int L2_cache_size;
int L2_assoc;
int L2_hit_time;
int L2_miss_time;
int L2_transfer_time;
int L2_bus_width;

// Main memory configuration values
int mem_sendaddr;
int mem_ready;
int mem_chunktime;
int mem_chunksize;

static int configHandler(
	void* user,
	const char* section,
	const char* name,
	const char* value )
{

#define SECTION_MATCH(s) strcasecmp(s, section) == 0
#define NAME_MATCH(n) strcasecmp(n, name) == 0

#define IF_VAR_SET(v)  \
if (NAME_MATCH(#v))    \
{                      \
	v = atoi(value);   \
}

#define ELSE_IF_VAR_SET(v)       \
else if (NAME_MATCH(#v))         \
{                                \
	v = atoi(value);             \
}

	if (SECTION_MATCH("L1Cache"))
	{
			IF_VAR_SET(L1_block_size)
			ELSE_IF_VAR_SET(L1_cache_size)
			ELSE_IF_VAR_SET(L1_assoc)
			ELSE_IF_VAR_SET(L1_hit_time)
			ELSE_IF_VAR_SET(L1_miss_time)
			ELSE_IF_VAR_SET(L1_miss_time)
			else
			{
					return 0;
			}
	}
	else if (SECTION_MATCH("L2Cache"))
	{
			IF_VAR_SET(L2_block_size)
			ELSE_IF_VAR_SET(L2_cache_size)
			ELSE_IF_VAR_SET(L2_assoc)
			ELSE_IF_VAR_SET(L2_hit_time)
			ELSE_IF_VAR_SET(L2_miss_time)
			ELSE_IF_VAR_SET(L2_transfer_time)
			ELSE_IF_VAR_SET(L2_bus_width)
			else
			{
					return 0;
			}
	}
	else if(SECTION_MATCH("MainMem"))
	{
			IF_VAR_SET(mem_sendaddr)
			ELSE_IF_VAR_SET(mem_ready)
			ELSE_IF_VAR_SET(mem_chunktime)
			ELSE_IF_VAR_SET(mem_chunksize)
			else
			{
					return 0;
			}
	}
	else
	{
			return 0;
	}

	return 1;
}

int readConfigFile(char* filename)
{
	int error;
	if ((error = ini_parse(filename, configHandler, 0)) < 0)
	{
			printf("Reading config file failed. Error %d", error);
			return 1;
	}

	return 0;
}

void printConfig(void)
{
	printf("========Memory System Configuration=============");
	printf("\n   L1 CACHE:\n");
	printf("      L1_cache_size = %d     L1_block_size= %d     L1_assoc = %d\n",
							L1_cache_size,
							L1_block_size,
							L1_assoc);
	printf("      L1_hit_time = %d     L1_miss_time = %d\n",L1_hit_time,L1_miss_time);

	printf("\n   L2 CACHE:\n");
	printf("      L1_cache_size = %d     L1_block_size= %d     L1_assoc = %d\n",
							L2_cache_size,
							L2_block_size,
							L2_assoc);
	printf("      L2_hit_time = %d     L2_miss_time = %d\n",L2_hit_time,L2_miss_time);
	printf("      L2_transfer_time = %d     L2_bus_width = %d\n",L2_transfer_time,L2_bus_width);

	printf("\n   MEMORY Config:\n");
	printf("      Memory Send Address Time = %d      Memory Ready Time = %d\n",mem_sendaddr,mem_ready);
	printf("      Memory Chunk Time = %d      Memory Chunk size = %d\n",mem_chunktime,mem_chunksize);
	printf("===============================================\n\n\n");
}
